home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / sendmail / ease-3.5 / src / parser.y < prev    next >
Encoding:
Lex Description  |  1991-10-15  |  25.7 KB  |  1,344 lines

  1. %{
  2. #ifdef FLUKE
  3. # ifndef LINT
  4.     static char RCSid[] = "@(#)FLUKE  $Header: /home/kreskin/u0/barnett/Src/Ease/ease/src/RCS/parser.y,v 3.4 1991/10/15 17:02:04 barnett Exp $";
  5. # endif LINT
  6. #endif FLUKE
  7.  
  8. /*
  9.  *    parser.y -- EASE parser.
  10.  *
  11.  *            Contains code for yacc(1) which produces a parser (y.tab.c)
  12.  *            for Ease, a specification format for sendmail configuration
  13.  *            files.
  14.  *
  15.  *    author   -- James S. Schoner, Purdue University Computing Center,
  16.  *                          West Lafayette, Indiana  47907
  17.  *
  18.  *    date     -- July 2, 1985
  19.  *
  20.  *    Copyright (c) 1985 by Purdue Research Foundation
  21.  *
  22.  *    All rights reserved.
  23.  *
  24.  * $Log: parser.y,v $
  25.  * Revision 3.4  1991/10/15  17:02:04  barnett
  26.  * Detect if (one_or_more) next ($2) error
  27.  *
  28.  * Revision 3.3  1991/09/09  16:33:23  barnett
  29.  * Minor bug fix release
  30.  *
  31.  * Revision 3.2  1991/05/16  10:45:25  barnett
  32.  * Better support for System V machines
  33.  * Support for machines with read only text segments
  34.  *
  35.  * Revision 3.1  1991/02/25  22:09:52  barnett
  36.  * Fixed some portability problems
  37.  *
  38.  * Revision 3.0  1991/02/22  18:50:27  barnett
  39.  * Added support for HP/UX and IDA sendmail.
  40.  *
  41.  * Revision 2.1  1990/01/30  15:48:35  jeff
  42.  * Added SunOS/Ultrix/IDA extensions  Jan 24, 1989 Bruce Barnett
  43.  *
  44.  * Version 2.0  90/01/30  15:44:34  jeff
  45.  * Baseline release for netwide posting.
  46.  * 
  47.  */
  48.  
  49. #include "fixstrings.h"
  50. #include <stdio.h>
  51. #include "symtab.h"
  52. #include <ctype.h>
  53. extern void       BindID ();
  54. extern void       EmitDef ();
  55. extern char      *ListAppend ();
  56. extern char       *MakeCond ();
  57. extern char      *MakeRStr ();
  58. extern char       *ConvOpt ();
  59. extern char      *ConvFlg ();
  60. extern char      *MacScan ();
  61. extern char      *ConvMat ();
  62. extern void       StartRuleset ();
  63. extern char      *MakePosTok ();
  64. extern char      *GetField ();
  65. extern char      *Bracket ();
  66. extern char      *DbmParen ();
  67. extern char      *MakeRSCall ();
  68. extern char      *CheckMailer ();
  69. extern char      *CheckRS ();
  70. extern char      *MakeField ();
  71. extern char       MakeMac ();
  72. extern void       AssignType ();
  73. extern void       RemoveSymbol ();
  74. extern void       yyerror ();
  75. extern void       FatalError ();
  76. extern short RMatch;        /* ruleset match flag               */
  77. extern short number_of_fields;    /* number of fields on the line          */
  78. #ifdef DATA_RW
  79. char *Cbuf = " ";        /* character buffer                 */
  80. char *Mbuf = "$ ";        /* macro buffer                        */
  81. #else
  82. char *Cbuf = NULL;
  83. char *Mbuf = NULL;
  84. extern char *Strdup(); 
  85. #endif
  86. char *Tsb;            /* pointer to temporary string buffer */
  87. char *Tsb1;            /* pointer to another temporary string buffer */
  88. char *Flaglist;            /* pointer to header flag list          */
  89.  
  90. #define DIM(x)    (sizeof x/sizeof x[0])
  91. extern int yychar;
  92. extern int    yydebug;
  93.  
  94. #ifndef    DATA_RW
  95. void InitParser()
  96. {
  97.     if(!(Cbuf = Strdup(" ")) || !(Mbuf = Strdup("$ ")))
  98.         FatalError("Out of memory in InitParser()", (char *)NULL);
  99. }
  100. #endif
  101.  
  102. static void    
  103. Free( ptr )
  104. char *ptr;
  105.   {
  106.       if (ptr == (char *)0) {
  107. /*      fprintf(stderr,"Freeing a null pointer\n"); */
  108.       } else {
  109.       if (free(ptr) < 0 ) {
  110.           fprintf(stderr,"Free() returned an error\n");
  111.       }
  112.       }
  113.       fflush(stderr);
  114.   };
  115. static char *
  116. yydisplay(ch)
  117.      register int ch;
  118. {
  119.     static char buf[15];
  120.     static char * token[] = {
  121. #include "y.tok.h"
  122.     0 };
  123.  
  124.     switch (ch) {
  125.       case 0:
  126.     return "[end of file]";
  127. /* YYERRCODE is 256. See below */
  128. /*      case YYERRCODE:
  129.     return "[error]"; */
  130.       case '\b':
  131.     return "'\\b'";
  132.       case '\f':
  133.     return "'\\f'";
  134.       case '\n':
  135.     return "'\\n'";
  136.       case '\r':
  137.     return "'\\r'";
  138.       case '\t':
  139.     return "'\\t'";
  140.     }
  141.     /* I should use YYERRCODE - but it hasn't been defined yet */
  142.     /* when /usr/lib/yaccpar is added to this file, it will be defined */
  143.     if (ch == 256 ) return ("[error]"); 
  144.     if (ch > 256 && ch < 256 + DIM(token))
  145.       return token[ch - 257];
  146.     if (isascii(ch) && isprint(ch))
  147.       sprintf(buf, "'%c'",ch);
  148.     else if (ch < 256)
  149.       sprintf(buf, "Char %o4.3o", ch);
  150.     else 
  151.       sprintf(buf, "token %d", ch);
  152.     return buf;
  153. }
  154. static yyyylex() 
  155. {
  156.     if (yychar < 0) {
  157.         /* don't make this match =yylex - because sed changes
  158.            =yylex to =yyyylex in the Makefile. 
  159.            the pieces it changes is in /usr/lib/yaccparr and I don't
  160.            want to modify THAT!  - bgb */
  161.  
  162.         if ((yychar = yylex ()) < 0)    /* call yylex, not yyyylex */
  163.             yychar = 0;
  164. #ifdef YYDEBUG
  165.     if (yydebug)
  166.         printf("[yydebug] reading %s\n",
  167.             yydisplay(yychar));
  168.         fflush(stdout);
  169. #endif
  170.         return yychar;
  171.     }
  172. }
  173.      
  174.  
  175. %}
  176.  
  177. %union {            /* value stack element type    */
  178.     int      ival;        /* integer token            */
  179.     char      *psb;        /* string token               */
  180.     struct he *phe;        /* pointer to hash entry       */
  181.     enum opts optval;    /* sendmail options           */
  182.     enum flgs flgval;    /* mailer flags               */
  183.     enum mats mpval;    /* mailer attribute parameters */
  184. }
  185.  
  186. %start config
  187.  
  188. %token     <phe>    IDENT
  189. %token  <psb>    SCONST
  190. %token  <ival>    ICONST SEPCHAR
  191. %token BIND CANON CLASS CONCAT FOR HEADER HOST HOSTNUM IF IFSET IN
  192. %token MACRO MAILER MAP MARGV MATCH MEOL MFLAGS MMAXSIZE MPATH
  193. %token MRECIPIENT MSENDER NEXT OPTIONS PRECEDENCE READCLASS RESOLVE
  194. %token RETRY RETURN RULESET TRUSTED USER
  195. %token YPALIAS YPMAP YPPASSWD EVAL RESOLVED QUOTE ASM PROGRAM DEFAULT ALIAS
  196. %token DBM
  197.  
  198. %token ASGN COLON COMMA DEFINE DOLLAR FIELD LBRACE LPAREN RBRACE
  199. %token RPAREN SEMI STAR SLASH
  200.  
  201. %token AAOPT AOPT BBOPT CCOPT COPT DDOPT DOPT DOPTB DOPTI DOPTQ EOPT
  202. %token EOPTE EOPTM EOPTP EOPTW EOPTZ FFOPT FOPT GOPT HHOPT IOPT LLOPT
  203. %token MOPT NNOPT NOPT OOPT PPOPT QOPT QQOPT ROPT SOPT SSOPT TOPT TTOPT
  204. %token UOPT VOPT WWOPT XOPT XXOPT YOPT YYOPT ZOPT ZZOPT
  205. %token RROPT BOPT SLOPT HOPT IIOPT
  206.  
  207. %token AAFLAG CCFLAG DDFLAG EEFLAG EFLAG FFFLAG FFLAG HFLAG IIFLAG LFLAG
  208. %token LLFLAG MFLAG MMFLAG NFLAG PFLAG PPFLAG RFLAG RRFLAG SFLAG SSFLAG
  209. %token UFLAG UUFLAG XFLAG XXFLAG
  210. %token HHFLAG VVFLAG BBFLAG
  211.  
  212. %type    <psb>        mval strval ifcon conval ifres elseres nameset namelist
  213. %type    <psb>        doptid eoptid idlist fcond dlist mflags route mdefs
  214. %type    <psb>        matchaddr matchtok action actionstmt mailerspec mtdef
  215. %type    <psb>        rwaddr rwtok ftype reftok rword cantok resolution
  216. %type    <psb>        dbmtok dbmval dbmvaltok dbmstuff
  217. %type    <psb>        userspec hword hostid dheader mdefine
  218. %type    <psb>        catstring catstringlist canval canvaltok
  219. %type    <ival>        anychar
  220. %type    <phe>        cdef
  221. %type    <optval>    optid
  222. %type    <flgval>    flagid
  223. %type    <mpval>        mvar
  224. %type    <psb>        ifresmatch elseresmatch ifresroute elseresroute 
  225. /* needed special class with no comma's allowed */
  226. %type    <ival>        anycharbutcomma
  227. %type    <psb>        matchaddrnocomma matchtoknocomma
  228.  
  229. %left COMMA
  230. %left LPAREN RPAREN
  231. %nonassoc SCONST
  232.  
  233. %%
  234. config        :    /* empty */
  235.         |    config blockdef
  236.         |    error blockdef
  237.         ;
  238.  
  239. blockdef    :    BIND bindings
  240.         |    MACRO macdefs
  241.         |    CLASS classdefs
  242.         |    OPTIONS optdefs
  243.         |    PRECEDENCE precdefs
  244.         |    TRUSTED tlist
  245.         |    HEADER hdefs
  246.         |    MAILER mlist
  247.         |    RULESET rdef
  248.         |    FIELD fdefs
  249.         ;
  250.  
  251. bindings    :    /* empty */
  252.         |    bindings IDENT ASGN RULESET ICONST SEMI {
  253.                 BindID ($2, $5, ID_RULESET);
  254.             }
  255.         |    error SEMI {
  256.                 yyerrok;
  257.             }
  258.         ;
  259.  
  260. macdefs        :    /* empty */
  261.         |    macdefs IDENT ASGN mdefine SEMI {
  262.                 EmitDef (def_macro, $2, $4, (char *) NULL);
  263.             }
  264.         |    error SEMI {
  265.                 yyerrok;
  266.             }
  267.         ;
  268.  
  269. /* macro value
  270.  * can be string
  271.  * or ifset()
  272.  * or concat
  273.  */
  274. mdefine            :       mval {
  275.                         $$ = $1;
  276.             }
  277.         |    IFSET LPAREN IDENT COMMA ifres RPAREN {
  278.                 $$ = MakeCond ($3, MacScan($5));
  279.             }
  280.         ;
  281. mval        :    strval                %prec COMMA {
  282.                 $$ = $1;
  283.             }
  284.         |    CONCAT LPAREN conval RPAREN {
  285.                 $$ = $3;
  286.             } 
  287.         ;
  288.  
  289. strval        :    SCONST {
  290.                 $$ = $1;
  291.             }
  292.         |    strval SCONST {
  293.                 $$ = ListAppend ($1, $2, (char *) NULL);
  294.                 Free ($1);
  295.             }
  296.         ;
  297.  
  298. /* conval specifies what can be in a concat() function */
  299. conval        :    strval COMMA ifcon {
  300.                 $$ = ListAppend ($1, $3, (char *) NULL);
  301.                 Free ($1);
  302.                 Free ($3);
  303.             }
  304.         |    ifcon COMMA strval {
  305.                 $$ = ListAppend ($1, $3, (char *) NULL);
  306.                 Free ($1);
  307.                 Free ($3);
  308.             }
  309.         |    ifcon {
  310.                 $$ = $1;
  311.             }
  312.         |    error {
  313.                 $$ = NULL;
  314.             }
  315.         ;
  316.  
  317. ifcon        :    IFSET LPAREN IDENT COMMA ifres RPAREN {
  318.                 $$ = MakeCond ($3, MacScan($5));
  319.             }
  320.         ;
  321.  
  322. ifres        :    mval elseres {
  323.                 if ($2 != NULL) {
  324.                     $$ = ListAppend ($1, $2, "$|");
  325.                     Free ($1);
  326.                     Free ($2);
  327.                 } else
  328.                     $$ = $1;
  329.             }
  330.         |    error {
  331.                 $$ = NULL;
  332.             }
  333.         ;
  334.  
  335. elseres        :    /* empty */ {
  336.                 $$ = NULL;
  337.             }
  338.         |    COMMA mval {
  339.                 $$ = $2;
  340.             }
  341.         ;
  342.  
  343. classdefs    :    /* empty */ 
  344.         |    classdefs IDENT ASGN nameset {
  345.                 EmitDef (def_class, $2, $4, (char *) NULL);
  346.             }
  347.                 |     classdefs ASM LPAREN SCONST RPAREN SEMI {
  348.                 printf("%s\n",$4);
  349.                         }
  350.         |    error
  351.         ;
  352.  
  353. nameset        :    LBRACE namelist RBRACE SEMI {
  354.                 $$ = $2;
  355.             }
  356.         |    LBRACE RBRACE SEMI {
  357.                 $$ = NULL;
  358.             }
  359.         |    LBRACE error RBRACE SEMI {
  360.                 $$ = NULL;
  361.             }
  362.         |    READCLASS LPAREN strval RPAREN SEMI {
  363.                 $$ = MakeRStr ($3, (char *) NULL);
  364.             }
  365.         |    READCLASS LPAREN strval COMMA strval RPAREN SEMI {
  366.                 $$ = MakeRStr ($3, $5);
  367.             }
  368.         |    READCLASS LPAREN error RPAREN SEMI {
  369.                 $$ = NULL;
  370.             }
  371.         |    error SEMI {
  372.                 $$ = NULL;
  373.                 yyerrok;
  374.             }
  375.         ;
  376.  
  377. namelist    :    IDENT {
  378.                 $$ = ListAppend ($1->psb, (char *) NULL, (char *) NULL);
  379.                 RemoveSymbol ($1);
  380.             }
  381.         |    strval {
  382.                 $$ = $1;
  383.             }
  384.         |    namelist COMMA IDENT {
  385.                 $$ = ListAppend ($1, $3->psb, " ");
  386.                 Free ($1);
  387.                 RemoveSymbol ($3);
  388.             }
  389.         |    namelist COMMA strval {
  390.                 $$ = ListAppend ($1, $3, " ");
  391.                 Free ($1);
  392.                 Free ($3);
  393.             }
  394.         ;
  395.  
  396. optdefs        :    /* empty */
  397.         |    optdefs optid ASGN strval SEMI {
  398.                 EmitDef (def_option, (struct he *) NULL, ConvOpt ($2), $4);
  399.             }
  400.         |    optdefs DOPT ASGN doptid SEMI {
  401.                 EmitDef (def_option, (struct he *) NULL, ConvOpt (opt_d), $4);
  402.             }
  403.         |    optdefs EOPT ASGN eoptid SEMI {
  404.                 EmitDef (def_option, (struct he *) NULL, ConvOpt (opt_e), $4);
  405.             }
  406.                 |     optdefs ASM LPAREN SCONST RPAREN SEMI {
  407.                 printf("%s\n",$4);
  408.                         }
  409.         |    error SEMI {
  410.                 yyerrok;
  411.             }
  412.         ;
  413.  
  414. optid        :    AAOPT {
  415.                 $$ = opt_A;
  416.             }
  417.         |    AOPT {
  418.                 $$ = opt_a;
  419.             }
  420.         |    BBOPT {
  421.                 $$ = opt_B;
  422.             }
  423.         |    BOPT {
  424.                 $$ = opt_b;
  425.             }
  426.         |    CCOPT {
  427.                 $$ = opt_C;
  428.             }
  429.         |    COPT {
  430.                 $$ = opt_c;
  431.             }
  432.         |    DDOPT {
  433.                 $$ = opt_D;
  434.             }
  435.         |    FFOPT {
  436.                 $$ = opt_F;
  437.             }
  438.         |    FOPT {
  439.                 $$ = opt_f;
  440.             }
  441.         |    GOPT {
  442.                 $$ = opt_g;
  443.             }
  444.         |    HOPT {
  445.                 $$ = opt_h;
  446.             }
  447.         |    HHOPT {
  448.                 $$ = opt_H;
  449.             }
  450.         |    IOPT {
  451.                 $$ = opt_i;
  452.             }
  453.         |    IIOPT {
  454.                 $$ = opt_I;
  455.             }
  456.         |    LLOPT {
  457.                 $$ = opt_L;
  458.             }
  459.         |    MOPT {
  460.                 $$ = opt_m;
  461.             }
  462.         |    NNOPT {
  463.                 $$ = opt_N;
  464.             }
  465.         |    NOPT {
  466.                 $$ = opt_n;
  467.             }
  468.         |    PPOPT {
  469.                 $$ = opt_P;
  470.             }
  471.         |    OOPT {
  472.                 $$ = opt_o;
  473.             }
  474.         |    QQOPT {
  475.                 $$ = opt_Q;
  476.             }
  477.         |    QOPT {
  478.                 $$ = opt_q;
  479.             }
  480.         |    ROPT {
  481.                 $$ = opt_r;
  482.             }
  483.         |    RROPT {
  484.                 $$ = opt_R;
  485.             }
  486.         |    SSOPT {
  487.                 $$ = opt_S;
  488.             }
  489.         |    SOPT {
  490.                 $$ = opt_s;
  491.             }
  492.         |    TTOPT {
  493.                 $$ = opt_T;
  494.             }
  495.         |    TOPT {
  496.                 $$ = opt_t;
  497.             }
  498.         |    UOPT {
  499.                 $$ = opt_u;
  500.             }
  501.         |    VOPT {
  502.                 $$ = opt_v;
  503.             }
  504.         |    WWOPT {
  505.                 $$ = opt_W;
  506.             }
  507.         |    XOPT {
  508.                 $$ = opt_x;
  509.             }
  510.         |    XXOPT {
  511.                 $$ = opt_X;
  512.             }
  513.         |    YOPT {
  514.                 $$ = opt_y;
  515.             }
  516.         |    YYOPT {
  517.                 $$ = opt_Y;
  518.             }
  519.         |    ZOPT {
  520.                 $$ = opt_z;
  521.             }
  522.         |    ZZOPT {
  523.                 $$ = opt_Z;
  524.             }
  525.         |    SLOPT {
  526.                 $$ = opt_SL;    /* SLASH .e.g. O/ in IDA */
  527.             }
  528.         ;
  529.  
  530. doptid        :    DOPTI {
  531.                 $$ = ConvOpt (d_opt_i);
  532.             }
  533.         |    DOPTB {
  534.                 $$ = ConvOpt (d_opt_b);
  535.             }
  536.         |    DOPTQ {
  537.                 $$ = ConvOpt (d_opt_q);
  538.             }
  539.         ;
  540.  
  541. eoptid        :    EOPTP {
  542.                 $$ = ConvOpt (e_opt_p);
  543.             }
  544.         |    EOPTE {
  545.                 $$ = ConvOpt (e_opt_e);
  546.             }
  547.         |    EOPTM {
  548.                 $$ = ConvOpt (e_opt_m);
  549.             }
  550.         |    EOPTW {
  551.                 $$ = ConvOpt (e_opt_w);
  552.             }
  553.         |    EOPTZ {
  554.                 $$ = ConvOpt (e_opt_z);
  555.             }
  556.         ;
  557.  
  558. precdefs    :    /* empty */
  559.         |    precdefs IDENT ASGN ICONST SEMI {
  560.                 BindID ($2, $4, ID_PREC);
  561.                 EmitDef (def_prec, $2, (char *) NULL, (char *) NULL);
  562.             }
  563.         ;
  564.  
  565. tlist        :    /* empty */
  566.         |    tlist LBRACE IDENT idlist RBRACE SEMI {
  567.                 EmitDef (def_trusted, (struct he *) NULL, 
  568.                      ListAppend ($3->psb, $4, " "), (char *) NULL);
  569.                 Free ($4); /* Gets a Null pointer */
  570.                 RemoveSymbol ($3);
  571.             }
  572.         |    tlist LBRACE RBRACE SEMI
  573.         |    error SEMI {
  574.                 yyerrok;
  575.             }
  576.         ;
  577.  
  578. hdefs        :    /* empty */
  579.         |    hdefs FOR fcond dheader SEMI {
  580.                 EmitDef (def_header, (struct he *) NULL, $3, $4);
  581.             }
  582.         |    hdefs FOR fcond LBRACE { Flaglist = $3; } 
  583.                 dheaders RBRACE SEMI
  584.         |    hdefs DEFINE dlist SEMI {
  585.                 EmitDef (def_header, (struct he *) NULL, (char *) NULL, $3);
  586.             }
  587.         |    error SEMI {
  588.                 yyerrok;
  589.             }
  590.         ;
  591.  
  592. fcond        :    LPAREN RPAREN {
  593.                 $$ = NULL;
  594.             }
  595.         |    LPAREN mflags RPAREN {
  596.                 $$ = $2;
  597.             }
  598.         |    LPAREN error RPAREN {
  599.                 $$ = NULL;
  600.             }
  601.         ;
  602.  
  603. mflags        :    flagid {
  604.                 $$ = ListAppend (ConvFlg ($1), (char *) NULL, (char *) NULL);
  605.             }
  606.         |    mflags COMMA flagid {
  607.                 $$ = ListAppend ($1, ConvFlg($3), (char *) NULL);
  608.                 Free ($1);
  609.             }
  610.         ;
  611.  
  612. flagid        :    FFLAG {
  613.                 $$ = flg_f;
  614.             }
  615.         |    RFLAG {
  616.                 $$ = flg_r;
  617.             }
  618.         |    SSFLAG {
  619.                 $$ = flg_S;
  620.             }
  621.         |    NFLAG {
  622.                 $$ = flg_n;
  623.             }
  624.         |    LFLAG {
  625.                 $$ = flg_l;
  626.             }
  627.         |    SFLAG {
  628.                 $$ = flg_s;
  629.             }
  630.         |    MFLAG {
  631.                 $$ = flg_m;
  632.             }
  633.         |    FFFLAG {
  634.                 $$ = flg_F;
  635.             }
  636.         |    DDFLAG {
  637.                 $$ = flg_D;
  638.             }
  639.         |    MMFLAG {
  640.                 $$ = flg_M;
  641.             }
  642.         |    XFLAG {
  643.                 $$ = flg_x;
  644.             }
  645.         |    PPFLAG {
  646.                 $$ = flg_P;
  647.             }
  648.         |    UFLAG {
  649.                 $$ = flg_u;
  650.             }
  651.         |    HFLAG {
  652.                 $$ = flg_h;
  653.             }
  654.         |    AAFLAG {
  655.                 $$ = flg_A;
  656.             }
  657.         |    BBFLAG {
  658.                 $$ = flg_B;
  659.             }
  660.         |    UUFLAG {
  661.                 $$ = flg_U;
  662.             }
  663.         |    EFLAG {
  664.                 $$ = flg_e;
  665.             }
  666.         |    XXFLAG {
  667.                 $$ = flg_X;
  668.             }
  669.         |    LLFLAG {
  670.                 $$ = flg_L;
  671.             }
  672.         |    PFLAG {
  673.                 $$ = flg_p;
  674.             }
  675.         |    IIFLAG {
  676.                 $$ = flg_I;
  677.             }
  678.         |    CCFLAG {
  679.                 $$ = flg_C;
  680.             }
  681.         |    EEFLAG {
  682.                 $$ = flg_E;
  683.             }
  684.         |    RRFLAG {
  685.                 $$ = flg_R;
  686.             }
  687.         |    HHFLAG {
  688.                 $$ = flg_H;
  689.             }
  690.         |    VVFLAG {
  691.                 $$ = flg_V;
  692.             }
  693.         ;
  694.  
  695. dheader        :    /* empty */ {
  696.                 $$ = NULL;
  697.             }
  698.         |    DEFINE dlist {
  699.                 $$ = $2;
  700.             }
  701.         |    error {
  702.                 $$ = NULL;
  703.             }
  704.         ;
  705.  
  706. dheaders    :    /* empty */
  707.         |    dheaders DEFINE dlist SEMI {
  708.                 EmitDef (def_header, (struct he *) NULL, Flaglist, $3);
  709.             }
  710.                 |     dheaders ASM LPAREN SCONST RPAREN SEMI {
  711.                 printf("%s\n",$4);
  712.                         }
  713.         |    error
  714.         ;
  715.  
  716. dlist        :    LPAREN strval COMMA catstringlist RPAREN {
  717.                 $$ = ListAppend ($2, MacScan ($4), " ");
  718.                 Free ($2);
  719.                 Free ($4);
  720.             }
  721.         |    LPAREN error RPAREN {
  722.                 $$ = NULL;
  723.             }
  724.         ;
  725.  
  726. catstringlist    :    catstring {
  727.                   $$ = $1;
  728.             }
  729.         |    catstring COMMA catstringlist {
  730.                   $$ = ListAppend( $1, $3, (char *) NULL);
  731.                   Free($1);
  732.             }
  733. catstring    :    SCONST {
  734.                 $$ = $1;
  735.             }
  736.         |    CONCAT LPAREN conval RPAREN {
  737.                 $$ = $3;
  738.             }
  739.         |    ifcon {
  740.                 $$ = $1;
  741.             }
  742.         ;
  743.  
  744. mlist        :    /* empty */
  745.         |    mlist IDENT LBRACE mdefs RBRACE SEMI {
  746.                 EmitDef (def_mailer, $2, $4, (char *) NULL);
  747.             }
  748.         |    mlist IDENT LBRACE RBRACE SEMI {
  749.                 EmitDef (def_mailer, $2, (char *) NULL, (char *) NULL);
  750.             }
  751.         |    error SEMI {
  752.                 yyerrok;
  753.             }
  754.         ;
  755.  
  756. mdefs        :    mtdef {
  757.                 $$ = $1;
  758.             }
  759.         |    mdefs COMMA mtdef {
  760.                 $$ = ListAppend ($1, $3, ", ");
  761.                 Free ($1);
  762.                 Free ($3);
  763.             }
  764.         ;    
  765.  
  766. mtdef        :    mvar ASGN mval {
  767.                 $$ = ListAppend (ConvMat ($1), MacScan ($3), "=");
  768.                 Free ($3);
  769.             }
  770.         |    MFLAGS ASGN LBRACE mflags RBRACE {
  771.                 $$ = ListAppend (ConvMat (mat_flags), $4, "=");
  772.             }
  773.         |    MSENDER ASGN IDENT {
  774.                 $$ = ListAppend (ConvMat (mat_sender), CheckRS ($3), "=");
  775.             }
  776.         |    MSENDER ASGN IDENT SLASH IDENT {
  777.                 $$ = ListAppend(
  778.                  Tsb = ListAppend (ConvMat(mat_sender), CheckRS ($3), "="),
  779.                  Tsb1 = ListAppend ("/", CheckRS ($5), (char *) NULL),
  780.                          (char *) NULL);
  781.                 Free (Tsb);
  782.                 Free (Tsb1);
  783.             }
  784.         |    MRECIPIENT ASGN IDENT {
  785.                 $$ = ListAppend (ConvMat (mat_recipient), CheckRS ($3), "=");
  786.             }
  787.         |    MRECIPIENT ASGN IDENT SLASH IDENT {
  788.                 $$ = ListAppend(
  789.                  Tsb = ListAppend (ConvMat(mat_recipient), CheckRS ($3), "="),
  790.                  Tsb1 = ListAppend ("/", CheckRS ($5), (char *) NULL),
  791.                          (char *) NULL);
  792.                 Free (Tsb);
  793.                 Free (Tsb1);
  794.             }
  795.         |    error {
  796.                 $$ = NULL;
  797.             }
  798.         ;
  799.  
  800. mvar        :    MPATH {
  801.                 $$ = mat_path;
  802.             }
  803.         |    MARGV {
  804.                 $$ = mat_argv;
  805.             }
  806.         |    MEOL {
  807.                 $$ = mat_eol;
  808.             }
  809.         |    MMAXSIZE {
  810.                 $$ = mat_maxsize;
  811.             }
  812.         ;
  813.  
  814. rdef        :    /* empty */
  815.         |    rdef IDENT { StartRuleset ($2); } rulelist
  816.         ;
  817.  
  818. rulelist    :    LBRACE ruledefs RBRACE {
  819.                 RMatch = FALSE;
  820.             }
  821.         |    error {
  822.                 RMatch = FALSE;
  823.             }
  824.         ;
  825.  
  826. ruledefs    :    /* empty */ {
  827.                 RMatch = TRUE;
  828.             }
  829.         |    ruledefs IF LPAREN matchaddr RPAREN actionstmt {
  830.                   number_of_fields    =0;
  831.                 EmitDef (def_ruleset, (struct he *) NULL, 
  832.                      ListAppend ($4, $6, "\t"), (char *) NULL);
  833.             Free ($4);
  834.             Free ($6);
  835.             }
  836.                 |     ruledefs ASM LPAREN SCONST RPAREN SEMI {
  837.                   printf("%s\n",$4);
  838.                         }
  839.         |    error SEMI {
  840.                 yyerrok;
  841.             }
  842.         ;
  843.  
  844. matchaddr    :    /* empty */ {
  845.                 $$ = NULL;
  846.             }
  847.         |    matchaddr matchtok {
  848.                 $$ = ListAppend ($1, $2, (char *) NULL);
  849.                 Free ($1); /* NULL */
  850.             }
  851.         |    error {
  852.                 $$ = NULL;
  853.             }
  854.         ;
  855.  
  856. /* just like matchaddr - but comma's aren't allowed */
  857. matchaddrnocomma    :    /* empty */ {
  858.                 $$ = NULL;
  859.             }
  860.         |    matchaddrnocomma matchtoknocomma {
  861.                 $$ = ListAppend ($1, $2, (char *) NULL);
  862.                 Free ($1); /* NULL */
  863.             }
  864.         |    error {
  865.                 $$ = NULL;
  866.             }
  867.         ;
  868.  
  869. matchtok    :    IDENT {
  870.                 $$ = GetField ($1);
  871.             }
  872.         |    anychar {
  873.                 *Cbuf = $1;
  874.                 $$ = ListAppend (Cbuf, (char *) NULL, (char *) NULL);
  875.             }
  876.         |    mval {
  877.                 $$ = MacScan ($1);
  878.             }
  879.         |    DOLLAR IDENT {
  880.                 Mbuf[1] = MakeMac ($2, ID_MACRO);
  881.                 $$ = ListAppend (Mbuf, (char *) NULL, (char *) NULL);
  882.             }
  883.                 |       YPALIAS LPAREN matchtok RPAREN {
  884.                  $$ = ListAppend("${",$3,(char *) NULL);
  885. /*             Free ($3); */
  886.         }
  887.                 |       YPPASSWD LPAREN matchtok RPAREN {
  888.                  $$ = ListAppend("$\"",$3,(char *) NULL);
  889.         }
  890.                 |       RESOLVED LPAREN matchtok RPAREN {
  891.                  $$ = ListAppend("$#",$3,(char *) NULL);
  892.         }
  893.         |    IFSET LPAREN IDENT COMMA ifresmatch RPAREN {
  894.                 $$ = MakeCond ($3, MacScan($5));
  895.             }
  896.     ;
  897.  
  898. /* the next one is just like matchtok - but you can't have a comma in it */
  899. matchtoknocomma    :    IDENT {
  900.                 $$ = GetField ($1);
  901.             }
  902.         |    anycharbutcomma {
  903.                 *Cbuf = $1;
  904.                 $$ = ListAppend (Cbuf, (char *) NULL, (char *) NULL);
  905.             }
  906.         |    mval {
  907.                 $$ = MacScan ($1);
  908.             }
  909.         |    DOLLAR IDENT {
  910.                 Mbuf[1] = MakeMac ($2, ID_MACRO);
  911.                 $$ = ListAppend (Mbuf, (char *) NULL, (char *) NULL);
  912.             }
  913.                 |       YPALIAS LPAREN matchtok RPAREN {
  914.                  $$ = ListAppend("${",$3,(char *) NULL);
  915. /*             Free ($3); */
  916.         }
  917.                 |       YPPASSWD LPAREN matchtok RPAREN {
  918.                  $$ = ListAppend("$\"",$3,(char *) NULL);
  919.         }
  920.                 |       RESOLVED LPAREN matchtok RPAREN {
  921.                  $$ = ListAppend("$#",$3,(char *) NULL);
  922.         }
  923.         |    IFSET LPAREN IDENT COMMA ifresmatch RPAREN {
  924.                 $$ = MakeCond ($3, MacScan($5));
  925.             }
  926.     ;
  927.  
  928. ifresmatch    :    matchaddrnocomma elseresmatch {
  929.                 if ($2 != NULL) {
  930.                     $$ = ListAppend ($1, $2, "$|");
  931.                     Free ($1);
  932.                     Free ($2);
  933.                 } else
  934.                     $$ = $1;
  935.             }
  936.         |    error {
  937.                 $$ = NULL;
  938.             }
  939.         ;
  940.  
  941. elseresmatch    :
  942.             COMMA matchaddrnocomma {
  943.                 $$ = $2;
  944.             }
  945.         ;
  946.  
  947. actionstmt    :    action LPAREN rwaddr RPAREN SEMI {
  948.                 $$ = ListAppend ($1, $3, (char *) NULL);
  949.                 Free ($3);
  950.             }
  951.         |    RESOLVE LPAREN resolution RPAREN SEMI {
  952.                 $$ = $3;
  953.             }
  954.         |    error SEMI {
  955.                 $$ = NULL;
  956.                 yyerrok;
  957.             }
  958.         ;
  959.  
  960. action        :    RETRY {
  961.                 $$ = NULL;
  962.             }
  963.         |    NEXT {
  964.                 $$ = "$:";
  965.             }
  966.         |    RETURN {
  967.                 $$ = "$@";
  968.             }
  969.         ;
  970.  
  971. rwaddr        :    /* empty */ {
  972.                 $$ = NULL;
  973.             }
  974.         |    rwaddr rwtok {
  975.                 $$ = ListAppend ($1, $2, (char *) NULL);
  976.                 Free ($1);    /* NULL */
  977.             }
  978.         |    rwaddr IDENT LPAREN rwaddr RPAREN {
  979.                 $$ = ListAppend ($1, (Tsb = MakeRSCall ($2, $4)), (char *) NULL);
  980.                 Free ($1);    /* NULL */
  981.                 Free ($4);
  982.                 Free (Tsb);
  983.             }
  984.         |    error {
  985.                 $$ = NULL;
  986.             }
  987.         ;
  988.  
  989. rwtok        :    anychar {
  990.                 *Cbuf = $1;
  991.                 $$ = ListAppend (Cbuf, (char *) NULL, (char *) NULL);
  992.             }
  993.         |    mval {
  994.                 $$ = MacScan ($1);
  995.             }
  996.         |    cantok {
  997.                 $$ = $1;
  998.             }
  999.         |    dbmtok {
  1000.                 $$ = $1;
  1001.             }
  1002.         |    ALIAS LPAREN reftok  RPAREN {
  1003.                 $$ = ListAppend("$(@", $3, "$:$)");
  1004.             }
  1005.         |    ALIAS LPAREN reftok DEFAULT LPAREN rwaddr RPAREN RPAREN {
  1006.                 $$ = ListAppend(Tsb = 
  1007.                         ListAppend ( "$(@", 
  1008.                                 $3, 
  1009.                                 (char *)NULL),
  1010.                         Tsb1 = ListAppend("$:", $6, "$)" ),
  1011.                         (char *) NULL);
  1012.                 Free (Tsb);
  1013.                 Free (Tsb1);
  1014.                 Free ($3);
  1015.                 Free ($6);
  1016.             }
  1017.         |    reftok {
  1018.                 $$ = $1;
  1019.             }
  1020.         |    ifcon {
  1021.                 $$ = $1;
  1022.             }
  1023.                 |    YPMAP LPAREN IDENT COMMA rwaddr RPAREN {
  1024.                 *Cbuf = MakeMac ($3, ID_MACRO);
  1025.                 $$ = ListAppend(Tsb = ListAppend ("${", (char *)Cbuf, (char *)NULL),
  1026.                         Tsb1 = ListAppend ($5, "$}", (char *) NULL),
  1027.                          (char *) NULL);
  1028.                 Free (Tsb);
  1029.                 Free (Tsb1);
  1030.                 Free ($5);
  1031.             }
  1032.  
  1033.                 |    PROGRAM LPAREN IDENT COMMA rwaddr RPAREN {
  1034.                 *Cbuf = MakeMac ($3, ID_MACRO);
  1035.                 $$ = ListAppend(Tsb = ListAppend ("$<", (char *)Cbuf, (char *)NULL),
  1036.                         Tsb1 = ListAppend ($5, "", (char *) NULL),
  1037.                          (char *) NULL);
  1038.                 Free (Tsb);
  1039.                 Free (Tsb1);
  1040.                 Free ($5);
  1041.             }
  1042.  
  1043.                 |    action LPAREN rwaddr RPAREN {
  1044.                 $$ = ListAppend ($1, $3, (char *) NULL);
  1045.                 Free ($3);
  1046.             }
  1047.         ;
  1048.  
  1049.  
  1050. cantok        :    CANON LPAREN canval RPAREN {
  1051.                 $$ = Bracket ($3, TRUE);
  1052.                 Free ($3);
  1053.             }
  1054.  
  1055.                 ;
  1056. canval        :    canvaltok {
  1057.                 $$ = $1;
  1058.             }
  1059.         |    canval canvaltok {
  1060.                 $$ = ListAppend ($1, $2, (char *) NULL);
  1061.                 Free ($1);
  1062. /*                Free ($2); */
  1063.             }
  1064.         ;
  1065.  
  1066. canvaltok    :    IDENT {
  1067.                 $$ = ListAppend ($1->psb, (char *) NULL, (char *) NULL);
  1068.                 RemoveSymbol ($1);
  1069.             }
  1070.         |    SCONST {
  1071.                 $$ = ListAppend (MacScan ($1), (char *) NULL, (char *) NULL);
  1072.                 Free ($1);
  1073.             }
  1074.                 |    NEXT LPAREN RPAREN {    /* I Used next earlier, but now use default - because it is clearer syntax */
  1075.                 $$ = "$:";
  1076.             }
  1077.                 |    NEXT LPAREN canval RPAREN {
  1078.                 $$ = ListAppend("$:", $3, (char *)NULL);
  1079.             }
  1080.                 |    DEFAULT LPAREN RPAREN {
  1081.                 $$ = "$:";
  1082.             }
  1083.                 |    DEFAULT LPAREN canval RPAREN {
  1084.                 $$ = ListAppend("$:", $3, (char *)NULL);
  1085.             }
  1086.         |    reftok {
  1087.                 $$ = $1;
  1088.             }
  1089.         |    SEPCHAR {
  1090.                 *Cbuf = $1;
  1091.                 $$ = ListAppend (Cbuf, (char *) NULL, (char *) NULL);
  1092.             }
  1093.         |    HOSTNUM LPAREN reftok RPAREN {
  1094.                 $$ = Bracket ($3, FALSE);
  1095.                 Free ($3);
  1096.             }
  1097.         ;
  1098.  
  1099. dbmtok        :    DBM LPAREN DOLLAR IDENT COMMA dbmstuff RPAREN {
  1100.                 $$ = DbmParen ($4->psb, $6);
  1101.                 RemoveSymbol($4);
  1102.                 Free ($6);
  1103.             }
  1104.                 ;
  1105. dbmstuff    :    dbmval COMMA dbmval {
  1106.                 $$ = ListAppend ($1, Tsb = ListAppend ("$@", $3, (char *) NULL),
  1107.                          (char *) NULL);
  1108.                 Free (Tsb);
  1109.             }
  1110.         |        dbmval {
  1111.                 $$ = $1;
  1112.             }
  1113.         ;
  1114.  
  1115. dbmval        :    dbmvaltok {
  1116.                 $$ = $1;
  1117.             }
  1118.         |    dbmval dbmvaltok {
  1119.                 $$ = ListAppend ($1, $2, (char *) NULL);
  1120.                 Free ($1);
  1121. /*                Free ($2); */
  1122.             }
  1123.         ;
  1124.  
  1125. dbmvaltok    :    IDENT {
  1126.                 $$ = ListAppend ($1->psb, (char *) NULL, (char *) NULL);
  1127.                 RemoveSymbol ($1);
  1128.             }
  1129.         |    SCONST {
  1130.                 $$ = ListAppend (MacScan ($1), (char *) NULL, (char *) NULL);
  1131.                 Free ($1);
  1132.             }
  1133.                 |    NEXT LPAREN RPAREN {    /* I Used next earlier, but now use default - because it is clearer syntax */
  1134.                 $$ = "$:";
  1135.             }
  1136.                 |    NEXT LPAREN dbmval RPAREN {
  1137.                 $$ = ListAppend("$:", $3, (char *)NULL);
  1138.             }
  1139.                 |    DEFAULT LPAREN RPAREN {
  1140.                 $$ = "$:";
  1141.             }
  1142.                 |    DEFAULT LPAREN dbmval RPAREN {
  1143.                 $$ = ListAppend("$:", $3, (char *)NULL);
  1144.             }
  1145.         |    reftok {
  1146.                 $$ = $1;
  1147.             }
  1148.         |    SEPCHAR {
  1149.                 *Cbuf = $1;
  1150.                 $$ = ListAppend (Cbuf, (char *) NULL, (char *) NULL);
  1151.             }
  1152.         ;
  1153.  
  1154. reftok        :    DOLLAR IDENT {
  1155.                 Mbuf[1] = MakeMac ($2, ID_MACRO);
  1156.                 $$ = ListAppend (Mbuf, (char *) NULL, (char *) NULL);
  1157.             }
  1158.         |    DOLLAR ICONST {
  1159.                 $$ = ListAppend (MakePosTok ($2), (char *) NULL, (char *) NULL);
  1160.             }
  1161.                 |    EVAL LPAREN IDENT RPAREN {
  1162.                 *Cbuf = MakeMac ($3, ID_MACRO);
  1163.                 $$ = ListAppend("$&", (char *)Cbuf, (char *)NULL);
  1164.             }
  1165.         ;
  1166.  
  1167.  
  1168. /* because of ifset, we have to treat comma's special
  1169.  otherwise ifset(a,b,c) might be ambiguous if
  1170.  c is an address with a comma in it.
  1171. */
  1172. anychar        :    anycharbutcomma {
  1173.                   $$ = $1;
  1174.         }
  1175.           |    COMMA {
  1176.                 $$ = ',';
  1177.             }
  1178.  
  1179.         ;
  1180.  
  1181. anycharbutcomma        :    SEPCHAR {
  1182.                 $$ = $1;
  1183.             }
  1184.         |    COLON {
  1185.                 $$ = ':';
  1186.             }
  1187.         |    STAR {
  1188.                 $$ = '*';
  1189.             }
  1190.         |    SEMI {
  1191.                 $$ = ';';
  1192.             }
  1193.         |    LBRACE {
  1194.                 $$ = '{';
  1195.             }
  1196.         |    RBRACE {
  1197.                 $$ = '}';
  1198.             }
  1199.         |    SLASH {
  1200.                 $$ = '/';
  1201.             }
  1202.         |    ASGN {
  1203.                 $$ = '=';
  1204.             }
  1205.         ;
  1206.  
  1207. resolution    :    mailerspec COMMA route {
  1208.                 $$ = ListAppend ($1, $3, (char *) NULL);
  1209.                 Free ($1);
  1210.                 Free ($3);
  1211.             }
  1212.         |    mailerspec {
  1213.             $$ = $1;
  1214.             }
  1215.         |    error {
  1216.                 $$ = NULL;
  1217.             }
  1218.         ;
  1219.  
  1220. mailerspec    :    MAILER LPAREN rword RPAREN {
  1221.                 $$ = ListAppend ("$#", $3, (char *) NULL);
  1222.             }
  1223.         ;
  1224.  
  1225. route        :    HOST LPAREN hword RPAREN COMMA userspec {
  1226.                 $$ = ListAppend (Tsb = ListAppend ("$@", $3, (char *) NULL),
  1227.                          $6, (char *) NULL);
  1228.                 Free (Tsb);
  1229.  
  1230.  
  1231.                 Free ($6);
  1232.             }
  1233.         |    userspec {
  1234.                 $$ = $1;
  1235.             }
  1236.         |    IFSET LPAREN IDENT COMMA ifresroute RPAREN {
  1237.                 $$ = MakeCond ($3, MacScan($5));
  1238.             }
  1239.         ;
  1240.  
  1241. ifresroute        :    LPAREN route RPAREN  elseresroute {
  1242.                 if ($4 != NULL) {
  1243.                     $$ = ListAppend ($2, $4, "$|");
  1244.                     Free ($2);
  1245.                     Free ($4);
  1246.                 } else
  1247.                     $$ = $2;
  1248.             }
  1249.         |    error {
  1250.                 $$ = NULL;
  1251.             }
  1252.         ;
  1253.  
  1254. elseresroute    :
  1255.             COMMA LPAREN route RPAREN {
  1256.                 $$ = $3;
  1257.             }
  1258.         ;
  1259.  
  1260. hword        :    hostid {
  1261.                 $$ = $1;
  1262.             }
  1263.         |    HOSTNUM LPAREN reftok RPAREN {
  1264.                 $$ = Bracket ($3, FALSE);
  1265.                 Free ($3);
  1266.             }
  1267.         ;
  1268.  
  1269. hostid        :    /* empty */ {
  1270.                 $$ = NULL;
  1271.             }
  1272.         |    hostid IDENT {
  1273.                 $$ = ListAppend ($1, $2->psb, (char *) NULL);
  1274.                 RemoveSymbol ($2);
  1275.                 Free ($1);
  1276.             }
  1277.         |    hostid rwtok {
  1278.                 $$ = ListAppend ($1, $2, (char *) NULL);
  1279.                 Free ($1);    /* NULL */
  1280.             }
  1281.         ;
  1282.  
  1283. userspec    :    USER LPAREN rwaddr RPAREN {
  1284.                 $$ = ListAppend ("$:", $3, (char *) NULL);
  1285.                 Free ($3);
  1286.             }
  1287.         ;
  1288.  
  1289. rword        :    IDENT {
  1290.                 $$ = CheckMailer ($1);
  1291.             }
  1292.         |    reftok {
  1293.                 $$ = $1;
  1294.             }
  1295.         ;
  1296.  
  1297. fdefs        :    /* empty */
  1298.         |    fdefs IDENT idlist COLON ftype SEMI {
  1299.                 AssignType (ListAppend ($2->psb, $3, " "), $5);
  1300.                 Free ($3);    /* NULL */
  1301.             }
  1302.         |    error SEMI {
  1303.                 yyerrok;
  1304.             }
  1305.         ;
  1306.  
  1307. idlist        :    /* empty */ {
  1308.                 $$ = NULL;
  1309.             }
  1310.         |    idlist COMMA IDENT {
  1311.                 $$ = ListAppend ($1, $3->psb, " ");
  1312.                 Free ($1);
  1313.             }
  1314.         ;
  1315.  
  1316. ftype        :    MATCH LPAREN ICONST RPAREN cdef {
  1317.                 $$ = ListAppend (MakeField ($3, $5, FALSE, FALSE), 
  1318.                              (char *) NULL, (char *) NULL);
  1319.             }
  1320.         |    MATCH LPAREN ICONST RPAREN MAP IDENT {
  1321.                 $$ = ListAppend (MakeField ($3, $6, FALSE, TRUE), 
  1322.                              (char *) NULL, (char *) NULL);
  1323.             }
  1324.         |    MATCH HOST {
  1325.                 $$ = ListAppend ("$%y", 
  1326.                              (char *) NULL, (char *) NULL);
  1327.             }
  1328.         |    MATCH LPAREN ICONST STAR RPAREN {
  1329.                 $$ = ListAppend (MakeField ($3, (struct he *) NULL, TRUE, FALSE), 
  1330.                          (char *) NULL, (char *) NULL);
  1331.             }
  1332.         |    error {
  1333.                 $$ = NULL;
  1334.             }
  1335.         ;
  1336.  
  1337. cdef        :    /* empty */ {
  1338.                 $$ = NULL;
  1339.             }
  1340.         |    IN IDENT {
  1341.                 $$ = $2;
  1342.             }
  1343.         ;
  1344.